package java;

import java.classe.Classe;
import java.classe.TokensSource;
import java.parametro.Parametro;
import java.util.ArrayList;

public class Metodo implements TokensSource {
	String nome = null;

	ListaParametros parametros = null;

	boolean statico = false;

	String modificador = null;

	String retorno = null;

	String logica = null;

	ListaAssignException assinaturaExcessoes = null;

	private ListaAnotacao anotacoes = null;

	boolean finaL = false;

	boolean synchronizeD = false;

	public Metodo(String nome) {
		this.nome = nome;
	}

	public String codigoFonte() {
		String modificador = this.modificador == null ? NONVALUE
				: this.modificador + ESPACO;
		String retorno = this.retorno == null ? VOID : this.retorno;
		String logica = this.logica == null ? NONVALUE : this.logica;
		String statico = this.statico ? STATIC + ESPACO : NONVALUE;
		String anotacao = this.anotacoes == null ? NONVALUE : this.anotacoes
				.codigoFonte()
				+ ESPACO;
		String excessoes = this.assinaturaExcessoes == null ? NONVALUE
				: this.assinaturaExcessoes.codigoFonte();
		String sync = this.synchronizeD ? SYNCHRONIZED + ESPACO : NONVALUE;

		String finaL = this.finaL ? FINAL + ESPACO : NONVALUE;

		return anotacao + modificador + sync + finaL + statico + retorno
				+ ESPACO + this.nome + INICIOPARENTECE + montarParametros()
				+ FIMPARENTECE + excessoes + INICIOBLOCO + logica + FIMBLOCO;
	}

	private String montarParametros() {
		return parametros == null ? NONVALUE : parametros.codigoFonte();
	}

	public void addParametro(Parametro parametro) {
		if (parametros == null)
			parametros = new ListaParametros();
		parametros.add(parametro);
	}

	public void setTipoRetorno(String retorno) {
		this.retorno = retorno;
	}

	public void isStatico(boolean statico) {
		this.statico = statico;
	}

	public void addAnotacao(Anotar anotacao) {
		if (this.anotacoes == null)
			this.anotacoes = new ListaAnotacao();
		this.anotacoes.add(anotacao);
	}

	public void addExceptionAssign(Classe classe) {
		if (this.assinaturaExcessoes == null)
			this.assinaturaExcessoes = new ListaAssignException();
		this.assinaturaExcessoes.add(classe);
	}

	class ListaAssignException extends ArrayList<Classe> {
		private static final long serialVersionUID = 839299212464437340L;

		String codigoFonte() {
			String s = THROWS + ESPACO + get(0).getNome();
			for (int i = 1; i < size(); i++) {
				s += VIRGULA + ESPACO + get(i).getNome();
			}
			return s;
		}
	}

	private class ListaParametros extends ArrayList<Parametro> {
		private static final long serialVersionUID = 103030499249L;

		String codigoFonte() {
			String s = get(0).codigoFonte();
			for (int i = 1; i < size(); i++) {
				s += VIRGULA + ESPACO + get(i).codigoFonte();
			}
			return s;
		}
	}

	class ListaAnotacao extends ArrayList<Anotar> {
		private static final long serialVersionUID = 839199216464467540L;

		String codigoFonte() {
			String s = get(0).codigoFonte();
			for (int i = 1; i < size(); i++) {
				s += "\n" + get(i).codigoFonte();
			}
			return s;
		}
	}

	public void isFinal(boolean finaL) {
		this.finaL = finaL;
	}

	public void isSynchronized(boolean sync) {
		this.synchronizeD = sync;
	}

	public void setLogica(String logica) {
		this.logica = logica;
	}

	public void setModificador(String modificador) {
		this.modificador = modificador;
	}

	public String getNome() {
		return nome;
	}

	public String toString() {
		return codigoFonte();
	}

	public boolean equals(Object obj) {
		return super.equals(obj) || obj.toString().equals(this.toString());
	}
}
